<?php
/**
 * Created by PhpStorm.
 * User: zhouliang
 * Date: 2017/12/21
 * Time: 10:51
 */

namespace App\Http\Common\Helper;

use App\Exceptions\UserException;

class Synchronized
{
    /**
     * 自动加锁执行
     * @param $lockKey string 锁key
     * @param callable|array $func
     * @param array $params
     * @param int $waitTime 等待时间，微秒，默认相当于是100毫秒
     * @param int $maxExecuteTime 最大执行时间 秒
     * @return mixed
     * @throws UserException
     * @throws \Exception
     */
    public static function lockAndTry($lockKey,  $func = [], $params = [], $waitTime = 100000, $maxExecuteTime = 10)
    {
        for ($i = 0; $i < 10; $i ++) {
            if (RedisHelper::incr($lockKey, $maxExecuteTime) == 1) {
                try {
                    return call_user_func_array($func, $params);
                } catch (\Exception $e) {
                    throw $e;
                } finally {
                    RedisHelper::deleteKey($lockKey);
                }
            }
            //等待时间随着循环次数增加
            $realWaitTime = $waitTime * $i ? $waitTime * $i : $waitTime;
            //等待，微秒
            usleep($realWaitTime);
        }
        LogHelper::warning('未获取到缓存锁', $params);
        throw new UserException('系统处理异常，请重试');
    }
}